package com.bestvike.stone.spring.redis.lock;

import com.bestvike.linq.exception.ArgumentException;
import com.bestvike.stone.spring.concurrent.LockObject;
import org.springframework.util.StringUtils;

/**
 * Redis 锁对象
 * Created by 许崇雷 on 2018/5/31.
 */
public final class RedisLockObject implements LockObject {
    private final String lockId;
    private final String lockName;
    private final String channelName;
    private final long leaseMillis;
    private RedisDistributedLock lock;

    /**
     * 构造函数
     *
     * @param lock        分布式锁
     * @param lockId      锁对象标识
     * @param lockName    锁对象名称
     * @param channelName 订阅频道名称
     * @param leaseMillis 持有毫秒数
     */
    public RedisLockObject(RedisDistributedLock lock, String lockId, String lockName, String channelName, long leaseMillis) {
        if (lock == null)
            throw new ArgumentException("lock can not be null.");
        if (StringUtils.isEmpty(lockId))
            throw new ArgumentException("lockId can not be empty.");
        if (StringUtils.isEmpty(lockName))
            throw new ArgumentException("lockName can not be empty.");
        if (StringUtils.isEmpty(channelName))
            throw new ArgumentException("channelName can not be empty.");
        if (leaseMillis <= 0)
            throw new ArgumentException("leaseMillis must greater than zero.");

        this.lock = lock;
        this.lockId = lockId;
        this.lockName = lockName;
        this.channelName = channelName;
        this.leaseMillis = leaseMillis;
    }

    /**
     * 获取锁对象标识
     */
    public String getLockId() {
        return this.lockId;
    }

    /**
     * 获取锁对象名称
     */
    public String getLockName() {
        return this.lockName;
    }

    /**
     * 获取订阅频道名称
     */
    public String getChannelName() {
        return this.channelName;
    }

    /**
     * 获取持有毫秒数
     */
    public long getLeaseMillis() {
        return this.leaseMillis;
    }

    /**
     * 续订锁
     */
    @Override
    public void renewal() {
        if (this.lock != null)
            this.lock.renewal(this);
    }

    /**
     * 释放锁
     */
    @Override
    public void close() {
        if (this.lock != null) {
            this.lock.release(this);
            this.lock = null;
        }
    }
}
